﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ChessSuite.Utilities.Common
{
    public struct BitBoard
    {
        public BitBoard(ulong internalBoard) : this()
        {
            // TODO: Complete member initialization
            this.InternalBoard = internalBoard;
        }

        public static ulong Zero { get { return 0UL; } }
        public static ulong One { get { return 1UL; } }

        private static BitBoard[] ranks = InitializeRanks();
        public static BitBoard[] Ranks { get { return ranks; } }
        private static BitBoard[] files = InitializeFiles();
        public static BitBoard[] Files { get { return files; } }

        public ulong InternalBoard { get; set; }

        public bool this[int file, int rank]
        {
            get
            {
                Position.ValidateCoordinate(file, rank);
                ulong uiMask = 1UL << (8 * rank + file);
                return (uiMask & this.InternalBoard) != 0;
            }
            set
            {
                Position.ValidateCoordinate(file, rank);
                ulong uiMask = 1UL << (8 * rank + file);
                if (value) InternalBoard |= uiMask;
                else InternalBoard &= ~uiMask;
            }
        }

        public int Count
        {
            get
            {
                UInt64 iCount = 0;
                UInt64 uiValue = InternalBoard;
                while (uiValue != 0)
                {
                    iCount += uiValue & 1UL;
                    uiValue >>= 1;
                }
                return (int)iCount;
            }
        }

        private static BitBoard[] InitializeRanks()
        {
            var res = new BitBoard[8];
            for (int rank = 0; rank < 8; ++rank)
                for (int file = 0; file < 8; ++file)
                    res[rank][file, rank] = true;
            return res;
        }

        private static BitBoard[] InitializeFiles()
        {
            var res = new BitBoard[8];
            for (int rank = 0; rank < 8; ++rank)
                for (int file = 0; file < 8; ++file)
                    res[file][file, rank] = true;
            return res;
        }
    }
}
